<template>
  <VueDragResize
    :key="key"
    class="b-dialog"
    :style="`--scale: ${dialogState.scale}`"
    :x="dialogState.position.x"
    :y="dialogState.position.y"
    :z="dialogState.position.z"
    :w="dialogState.position.w"
    :h="dialogState.position.h"
    :minw="300"
    :minh="100"
    @clicked="handleClick"
    @deactivated="handleDeactivated"
    @resizestop="handleResizeStop"
    @resizing="handleResizing"
    @dragstop="handleDragStop"
    v-if="!closed"
  >
    <div class="header" @dblclick="toggleMaximize">
      <div class="title" :title="title">{{ title }}</div>
      <div class="tools" v-show="!hideTools">
        <div class="iconfont icon-min" title="最小化" @click="handleZoomMin"></div>
        <div class="iconfont icon-fangda" title="最大化" @click="toggleMaximize"></div>
        <div class="iconfont icon-x" title="关闭" @click="handleDelete"></div>
      </div>
    </div>

    <div class="content">
      <Comp :params="CompParams" @close="handleClose"></Comp>
    </div>

    <div class="line-top"></div>
    <div class="line-bottom"></div>
    <div class="line-left"></div>
    <div class="line-right"></div>
  </VueDragResize>
</template>
<script setup lang="ts">
import VueDragResize from 'vue-drag-resize/src'
import { bDialogProps } from './dialog'
import { reactive, ref, toRef } from 'vue'
import { useZIndex } from 'element-plus'
import BDialog from '.'

const props = defineProps(bDialogProps)
const Comp = toRef(props, 'Comp')

function handleClick() {
  recoverZindex()
}

function handleDeactivated() {
  const { nextZIndex } = useZIndex()
  dialogState.position.z = nextZIndex()
}

function handleResizeStop() {
  console.log('resize stop')
}

const handleClose = (res?: any) => {
  if (props.onClose) {
    props.onClose(res)
  }
}

function recoverZindex() {
  dialogState.position.z = props.zIndex
}

const BASE_SCALE = 0.6
const SCALE_RATE = 0.002
const dialogState = reactive({
  position: {
    x: props.left,
    y: props.top,
    z: props.zIndex,
    w: props.width,
    h: props.height
  },
  previous: {
    x: props.left,
    y: props.top,
    w: props.width,
    h: props.height
  },
  scale: BASE_SCALE
})

const key = ref(Date.now())

function handleZoomMin() {
  console.log('zoom min')
}

function toggleMaximize() {
  const box = document.querySelector('#dialog-box')
  if (!box) return
  const { width, height } = box.getBoundingClientRect()
  if (width - 32 === dialogState.position.w && height - 32 === dialogState.position.h) {
    Object.assign(dialogState.position, dialogState.previous)
  } else {
    Object.assign(dialogState.previous, dialogState.position)
    Object.assign(dialogState.position, {
      w: width - 32,
      h: height - 32,
      x: 16,
      y: 16
    })
  }
  handleResizing({
    width: dialogState.position.w,
    height: dialogState.position.h,
    left: dialogState.position.x,
    top: dialogState.position.y
  })
  key.value = Date.now()
}

const closed = ref(false)
function handleDelete() {
  closed.value = true
  BDialog.close(props.id, props.onClose)
}

handleResizing({ width: props.width, height: props.height, left: props.left, top: props.top })

function handleResizing(rect: { left: number; top: number; width: number; height: number }) {
  const { width, height } = rect

  Object.assign(dialogState.position, {
    w: width,
    h: height
  })

  const rate = 500 - width
  dialogState.scale = rate > 0 ? 1 - SCALE_RATE * rate : 1
}

function handleDragStop(rect: { left: number; top: number; width: number; height: number }) {
  Object.assign(dialogState.position, {
    x: rect.left,
    y: rect.top
  })
}

defineExpose({
  recoverZindex,
  handleDelete
})
</script>
<style lang="scss" scoped>
.b-dialog {
  box-shadow: 0 0 4px var(--text-color-dark);
  background-color: var(--bg-color-page);
  font-size: calc(16px * var(--scale));
  pointer-events: auto;
  :deep(.content-container) {
    padding: calc(16px * var(--scale));
    overflow: hidden;
    display: flex;
    flex-direction: column;
    .content {
      flex: 1;
      overflow: auto;
    }
  }

  .header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    height: calc(35px * var(--scale));
    margin-bottom: calc(16px * var(--scale));

    .title {
      min-width: calc(286px * var(--scale));
      line-height: calc(35px * var(--scale));
      padding-left: calc(14px * var(--scale));
      padding-right: calc(100px * var(--scale));
      height: calc(35px * var(--scale));
      background-image: url('@/assets/images/bdialog/title-bg.png');
      background-size: 100% 100%;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    .tools {
      display: flex;
      justify-content: space-between;
      align-items: center;

      .iconfont {
        width: calc(20px * var(--scale));
        height: calc(20px * var(--scale));
        font-size: calc(20px * var(--scale));
        color: var(--el-color-primary);
        cursor: pointer;

        &:not(:last-child) {
          margin-right: calc(16px * var(--scale));
        }

        &:hover {
          color: var(--el-color-primary-light-3);
        }
      }
    }
  }

  &.active::before {
    outline: none;
  }

  :deep(.vdr-stick) {
    opacity: 0;
    &.vdr-stick-tm,
    &.vdr-stick-bm {
      width: calc(100% - 12px) !important;
      left: 10px;
    }

    &.vdr-stick-ml,
    &.vdr-stick-mr {
      height: calc(100% - 12px) !important;
      top: 10px;
    }
  }

  .line-top,
  .line-bottom {
    position: absolute;
    width: calc(300px * var(--scale));
    height: 1px;
    background: linear-gradient(90deg, rgba(0, 255, 167, 0), rgb(0, 255, 167) 100%);
  }

  .line-right,
  .line-left {
    position: absolute;
    width: 1px;
    height: calc(300px * var(--scale));
    background: linear-gradient(180deg, rgba(0, 255, 167, 0), rgb(0, 255, 167) 100%);
  }

  .line-top {
    left: 0;
    top: 0;
    transform: translateX(-100%);
  }

  .line-right {
    right: 0;
    top: 0;
    transform: translateY(-100%);
  }

  .line-bottom {
    right: 0;
    bottom: 0;
    transform: rotateZ(180deg) translateX(-100%);
  }

  .line-left {
    left: 0;
    bottom: 0;
    transform: rotateZ(180deg) translateY(-100%);
  }

  &.active {
    .line-top {
      animation: translateTop 4s linear infinite;
    }

    .line-right {
      animation: translateRight 4s 3.2s linear infinite;
    }

    .line-bottom {
      animation: translateBottom 4s 6.4s linear infinite;
    }

    .line-left {
      animation: translateLeft 4s 9.6s linear infinite;
    }
  }
}

@keyframes translateTop {
  0% {
    left: 0;
  }

  80% {
    left: 100%;
  }

  100% {
    left: calc(100% + calc(300px * var(--scale)));
  }
}

@keyframes translateRight {
  0% {
    top: 0;
  }

  80% {
    top: 100%;
  }

  100% {
    top: calc(100% + calc(300px * var(--scale)));
  }
}

@keyframes translateBottom {
  0% {
    right: 0;
  }

  80% {
    right: 100%;
  }

  100% {
    right: calc(100% + calc(300px * var(--scale)));
  }
}

@keyframes translateLeft {
  0% {
    bottom: 0;
  }

  80% {
    bottom: 100%;
  }

  100% {
    bottom: calc(100% + calc(300px * var(--scale)));
  }
}
</style>
